#include <QtGlobal>
#include <QDir>
#include <QList>
#include <QTextStream>

#include "OptAndroidDocs.h"

OptAndroidDocs::OptAndroidDocs()
{
    OptAndroidDocs(NULL);
}

OptAndroidDocs::OptAndroidDocs(const char *docsPath)
{
    mDocsPath = docsPath;

    mTagMap.insert("<link", ">");
    mTagMap.insert("<script", "</script>");

    mKeyWords << "fonts.googleapis.com";
    mKeyWords << "www.google.com/jsapi";
    mKeyWords << "www.google-analytics.com";

    mTextCodec = QTextCodec::codecForName("UTF-8");

}

void OptAndroidDocs::start()
{
    QDir *docDir = NULL;

    if (NULL == mDocsPath) {
        docDir = new QDir(QDir::current());
    } else {
        docDir = new QDir(QString(mDocsPath));
    }

    handleDir(*docDir);

    delete docDir;

}

void OptAndroidDocs::handleDir(QDir dir)
{

    dir.setFilter(QDir::Dirs | QDir::Files);
    QFileInfoList fileInfoList = dir.entryInfoList();
    QFileInfo fileInfo;

    for (int i=0; i<fileInfoList.count(); i++) {

        fileInfo = fileInfoList.at(i);

        if (!fileInfo.isReadable()) {
            continue;
        }
        if (fileInfo.isDir() &&
            fileInfo.fileName() != "." &&
            fileInfo.fileName() != "..") {
            handleDir(QDir(fileInfo.absoluteFilePath()));
        } else if (fileInfo.isFile()) {
            handleFile(fileInfo.absoluteFilePath());
        }
    }
}

void OptAndroidDocs::handleFile(QString filePath)
{
    if (!filePath.endsWith(".html")) {
        return;
    }
    //qDebug("Handle:%s", filePath.toStdString().c_str());

    QString filePathBak = filePath + ".bak";

    QFile htmlFile(filePath);
    QFile htmlBak(filePathBak);

    if (!htmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning("Open HTML [%s] failed", filePath.toStdString().c_str());
        return;
    }

    QTextStream content(&htmlFile);
    QTextStream *out = NULL;

    content.setCodec(mTextCodec);

    QString html;
    QString removedHtml;
    QString line;
    QString tmpHtml;

    bool foundStartTag	= false;
    bool foundEndTag	= false;
    bool foundKeyWord 	= false;
    bool handleFinish	= false;

    while (!(line = content.readLine()).isNull()) {

        line.append("\n");

        if (handleFinish) {
            (*out) << line;
            continue;
        }

        if (!foundStartTag && hasStartTag(line)) {
            foundStartTag 	= true;
        }

        if (hasKeyWord(line)) {
            foundKeyWord = true;
        }

        if (hasEndTag(line)) {
            tmpHtml += line;
            if (foundKeyWord) {
                removedHtml += tmpHtml;
            } else {
                html += tmpHtml;
            }
            tmpHtml = "";
            foundEndTag	= true;
            foundStartTag	= false;
            foundKeyWord 	= false;
        }

        if (foundStartTag) {
            tmpHtml += line;
        } else if(foundEndTag){
            foundEndTag = false;
        } else {
            html += line;
        }

        if (hasFinishTag(line)) {

            if (removedHtml.isNull() || removedHtml.isEmpty()) {
                break;
            }

            if (!htmlBak.open(QIODevice::WriteOnly | QIODevice::Text)) {
                qWarning("Open HTML [%s] failed", filePathBak.toStdString().c_str());
                break;
            }

            out = new QTextStream(&htmlBak);
            out->setCodec(mTextCodec);

            handleFinish = true;
            (*out) << html;
        }

    }


    htmlFile.close();

    if (NULL != out) {
        out->flush();
        htmlBak.close();
        delete out;
        QFile::remove(filePath);
        QFile::rename(filePathBak, filePath);
    }
    /*
    else if (!removedHtml.isNull() && !removedHtml.isEmpty()) {
        qDebug("removed html:\n%s", removedHtml.toStdString().c_str());
    }*/

}

bool OptAndroidDocs::hasStartTag(QString line)
{
    for (int i=0; i<mTagMap.keys().length(); i++) {
        mStartTag = mTagMap.keys().at(i);
        if (line.contains(mStartTag, Qt::CaseInsensitive)) {
            return true;
        }
    }
    return false;
}

bool OptAndroidDocs::hasEndTag(QString line)
{

    QString endTag = mTagMap.value(mStartTag);
    if (line.contains(endTag, Qt::CaseInsensitive)) {
        return true;
    }
    return false;
}

bool OptAndroidDocs::hasKeyWord(QString line)
{
    for (int i=0; i<mKeyWords.length(); i++) {
        if (line.contains(mKeyWords.at(i), Qt::CaseInsensitive)) {
            return true;
        }
    }
    return false;
}

bool OptAndroidDocs::hasFinishTag(QString line)
{
    if (line.contains("</head>") ||
        line.contains("</html>", Qt::CaseInsensitive)) {
        return true;
    }
    return false;
}
